package com.zmn.oms.third.shunfeng;

import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.HttpUtil;
import com.zmn.oms.third.shunfeng.dto.SFBaseRequestDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Objects;

/**
 * 顺丰安装渠道对接的工具类
 *
 * @author xiewenbing
 * @date 2020/12/09
 */
@Slf4j
public class ShunfengUtil {

    /**
     * 给请求数据生成签名
     *
     * @param sfBaseRequestDTO
     */
    public static void makeSign(SFBaseRequestDTO sfBaseRequestDTO) {

        if(Objects.isNull(sfBaseRequestDTO)) {
            return;
        }

        StringBuilder sbSign = new StringBuilder();
        sbSign.append(sfBaseRequestDTO.getMsgData()).append(sfBaseRequestDTO.getTimestamp().toString()).append(ShunfengConsts.MD5_KEY);

        String sign = encryptData(sbSign.toString());

        sfBaseRequestDTO.setMsgDigest(sign);

        log.info("【{}】生成签名，【{}】【{}】",ShunfengConsts.CHANNEL_NAME,sbSign.toString(),sign);
    }

    /**
     * 验证请求数据签名
     *
     * @param requestDTO
     * @return
     */
    public static boolean verifySign(SFBaseRequestDTO requestDTO) {

        if(Objects.isNull(requestDTO) || StringUtils.isBlank(requestDTO.getMsgDigest())) {
            return false;
        }

        StringBuilder sbSign = new StringBuilder();
        sbSign.append(requestDTO.getMsgData()).append(requestDTO.getTimestamp().toString()).append(ShunfengConsts.MD5_KEY);
        String sign = encryptData(sbSign.toString());

        log.info("【{}】生成签名，【{}】【{}】【{}】",ShunfengConsts.CHANNEL_NAME, sbSign.toString(), sign, requestDTO.getMsgDigest());
        return sign.compareToIgnoreCase(requestDTO.getMsgDigest()) == 0 ? true : false;
    }

    /**
     * 加密数据，得到签名
     *
     * @return
     */
    public static String encryptData(String encryptText) {

        if (StringUtils.isBlank(encryptText)) {
            return "";
        }

        String msgDigest = "";
        try {
            //因业务报文中可能包含加号、空格等特殊字符，需要urlEnCode处理
            String signContent = URLEncoder.encode(encryptText, "UTF-8");

            //进行Md5加密
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(signContent.getBytes("UTF-8"));
            byte[] md = md5.digest();

            //通过BASE64生成数字签名
            msgDigest = new String(new BASE64Encoder().encode(md));

        } catch (UnsupportedEncodingException unsupportedEncodingException) {

            log.info("【{}】生成签名数据，UnsupportedEncodingException【{}】，数据【{}】",ShunfengConsts.CHANNEL_NAME,
                    unsupportedEncodingException, encryptText);
        } catch (NoSuchAlgorithmException noSuchAlgorithmException) {

            log.info("【{}】生成签名数据，noSuchAlgorithmException【{}】，数据【{}】",ShunfengConsts.CHANNEL_NAME,
                    noSuchAlgorithmException, encryptText);
        }finally {
            return msgDigest;   
        }
    }
    /**
     * 发送 带参数请求
     * @param url
     * @param params
     * @return
     * @throws OmsBaseException
     */
    public static String postHttpRequest(String url, Map<String,String> params) {

        if (StringUtils.isBlank(url) || MapUtils.isEmpty(params)) {
            log.info("【{}】发送请求失败，参数不能为空",ShunfengConsts.CHANNEL_NAME);
            return null;
        }

        log.info("【{}】发送请求，URL【{}】,参数【{}】",ShunfengConsts.CHANNEL_NAME,url,params.toString());

        String response = "";
        for (int i=0; i<3; i++) {
            try {
                if (url.matches("https(.*)")) {
                    response = HttpUtil.httpsPost(url, params);
                } else {
                    response = HttpUtil.httpPost(url, params);
                }

                if (StringUtil.isNotBlank(response)) {
                    break;
                }
            } catch (Exception exception) {
                log.info("【{}】发送请求失败,{}",ShunfengConsts.CHANNEL_NAME,Objects.nonNull(exception)? exception.getMessage():"网络请求异常");
            }
        }

        log.info("【{}】发送请求应答【{}】",ShunfengConsts.CHANNEL_NAME,response);
        return response;
    }


}
